<?php

class model_application extends model
{

	public function get_list()
	{
		$db = bone::get_db();
		return $db->get_object_list( 'SELECT * FROM `bone_application`' );
	}

	public function get_frontend_controller_list($application_id=0)
	{
		$db = bone::get_db();
		if($application_id==0)
			return $db->get_objects( 'SELECT * FROM `bone_application_frontend_controller`' );
		else
			return $db->get_objects( 'SELECT * FROM `bone_application_frontend_controller` WHERE `application_id`='.$application_id );
	}

	public function get_backend_controller_list($application_id=0)
	{
		$db = bone::get_db();
		if($application_id==0)
			return $db->get_objects( 'SELECT * FROM `bone_application_backend_controller`' );
		else
			return $db->get_objects( 'SELECT * FROM `bone_application_backend_controller` WHERE `application_id`='.$application_id );
	}


	public function validate($application_id, $application_name)
	{
		$db = bone::get_db();
		if( $db->get_result( 'SELECT COUNT(*) FROM `bone_application` WHERE `application_id`='.$application_id ) )
		{
			$this->set_error('您已安装此应用('.$application_id.')');
			return false;
		}

		if( $db->get_result( 'SELECT COUNT(*) FROM `bone_application` WHERE `application`=\''.$application_name.'\'' ) )
		{
			$this->set_error('已存在命名为 '.$application_name.' 的应用');
			return false;
		}

		return true;
	}


	// 复制文件
	public function install($application_id, $application_name, $dir)
	{
		if( !file_exists($dir) )
		{
			$this->set_error('临时目录不存在 '.$dir);
			return false;
		}

		if( !( file_exists($dir.DS.'frontend') || file_exists($dir.DS.'backend')) )
		{
			$this->set_error('安装包目录结构错误, 未找到 frontend 和 backend 文件夹');
			return false;
		}


		$fso = bone::get('fso');
		$len = strlen($application_name);

		$install_log = array();


		// 复制前台文件
		if ( is_dir($dir.DS.'frontend') )
		{
			// 前台自动运行文件
			$file = $dir.DS.'frontend'.DS.'autorun.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.'autorun'.DS.$application_name.'.php');
				$install_log[] = '@frontend/autorun/'.$application_name.'.php';
			}

			// 前台配置文件
			$file = $dir.DS.'frontend'.DS.'config.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.'configs'.DS.$application_name.'.php');
				$install_log[] = '@frontend/configs/'.$application_name.'.php';
			}


			// 前台控制器
			$file = $dir.DS.'frontend'.DS.'controller.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.'controllers'.DS.$application_name.'.php');
				$install_log[] = '@frontend/controllers/'.$application_name.'.php';
			}



			// 前台模型
			$file = $dir.DS.'frontend'.DS.'model.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.'models'.DS.$application_name.'.php');
				$install_log[] = '@frontend/models/'.$application_name.'.php';
			}



			// 前台数据表
			$current_dir = $dir.DS.'frontend'.DS.'table';
			if(is_dir($current_dir))
			{
				$handle = opendir($current_dir);
				while (($file = readdir($handle)) !== false)
				{
					if( $file != '.' && $file != '..' )
					{
						if(is_file($current_dir.DS.$file))
						{
							if(substr($file, 0, $len)==$application_name)
							{
								@copy($current_dir.DS.$file, BONE_ROOT.DS.'tables'.DS.$file);
								$install_log[] = '@frontend/tables/'.$file;
							}
						}
					}
				}
				closedir($handle);
			}

			// 前台模板
			$current_dir = $dir.DS.'frontend'.DS.'template';
			if(is_dir($current_dir))
			{
				$fso->copy_dir($current_dir, BONE_ROOT.DS.'templates'.DS.$application_name);
				$install_log[] = '@frontend/templates/'.$application_name;
			}

		}


		// 复制后台文件
		if ( is_dir($dir.DS.'backend') )
		{
			
			// 后台配置文件
			$file = $dir.DS.'backend'.DS.'config.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.APP_DIR.DS.'configs'.DS.$application_name.'.php');
				$install_log[] = '@backend/configs/'.$application_name.'.php';
			}



			// 后台控制器
			$file = $dir.DS.'backend'.DS.'controller.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.APP_DIR.DS.'controllers'.DS.$application_name.'.php');
				$install_log[] = '@backend/controllers/'.$application_name.'.php';
			}


			// 后台模型
			$file = $dir.DS.'backend'.DS.'model.php';
			if(file_exists($file))
			{
				@copy($file, BONE_ROOT.DS.APP_DIR.DS.'models'.DS.$application_name.'.php');
				$install_log[] = '@backend/models/'.$application_name.'.php';
			}


			// 后台数据表
			$current_dir = $dir.DS.'backend'.DS.'table';
			if(is_dir($current_dir))
			{
				$handle = opendir($current_dir);
				while (($file = readdir($handle)) !== false)
				{
					if( $file != '.' && $file != '..' )
					{
						if(is_file($current_dir.DS.$file))
						{
							if(substr($file, 0, $len)==$application_name)
							{
								@copy($current_dir.DS.$file, BONE_ROOT.DS.APP_DIR.DS.'tables'.DS.$file);
								$install_log[] = '@backend/tables/'.$file;
							}
						}
					}
				}
				closedir($handle);
			}

			// 后台模板
			$current_dir = $dir.DS.'backend'.DS.'template';
			if(is_dir($current_dir))
			{
				$fso->copy_dir($current_dir, BONE_ROOT.DS.APP_DIR.DS.'templates'.DS.$application_name);
				$install_log[] = '@backend/templates/'.$application_name;
			}

		}


		$db = bone::get_db();
		$install_sql = $dir.DS.'install.sql';
		$uninstall_sql = $dir.DS.'uninstall.sql';

		if(file_exists($install_sql))
		{
			$queries = $this->split_sql( file_get_contents($install_sql) );
			foreach($queries as $query)
				$db->execute( $query );
		}
		if(file_exists($uninstall_sql)) @copy($uninstall_sql, BONE_ROOT.DS.APP_DIR.DS.'storage'.DS.'applications'.DS.'sql'.DS.'uninstall_'.$application_id.'.sql');


		$table = bone::get_table('application_install_log', APP_DIR);
		if(count($install_log))
		{
			foreach($install_log as $log)
			{
				$table->id=0;
				$table->application_id = $application_id;
				$table->file = $log;
				$table->save();
			}
		}

		return true;
	}



	// 删除应用
	public function uninstall($id)
	{
		$db = bone::get_db();

		$table = bone::get_table('application', APP_DIR);
		$table->load($id);

		$application_id = $table->application_id;
		$application_name = $table->application;

		if(!$application_id)
		{
			$this->set_error('数据库中未找到该应用的资料');
			return false;
		}

		if($db->get_result( 'SELECT COUNT(*) FROM `bone_menu` WHERE `controller`=\''.$application_name.'\'' ))
		{
			$this->set_error('检测到有菜单连接到此应用');
			return false;
		}

		// 删除相关文件
		$package =  $application_id.'.zip';
		$thumbnail = array_pop(explode('/',$table->thumbnail ));
		$image = array_pop(explode('/',$table->image ));
		$uninstall_sql = 'uninstall_'.$application_id.'.sql';

		$path = BONE_ROOT.DS.APP_DIR.DS.'storage'.DS.'applications';
		$package_path = $path.DS.'packages'.DS.$package;
		$thumbnail_path = $path.DS.'thumbnails'.DS.$thumbnail;
		$image_path = $path.DS.'images'.DS.$image;
		$uninstall_sql_path = $path.DS.'sql'.DS.$uninstall_sql;

		if(file_exists($package_path)) unlink($package_path);
		if(file_exists($thumbnail_path)) unlink($thumbnail_path);
		if(file_exists($image_path)) unlink($image_path);
		if(file_exists($uninstall_sql_path))
		{
			$queries = $this->split_sql( file_get_contents($uninstall_sql_path) );
			foreach($queries as $query)
				$db->execute( $query );

			unlink($uninstall_sql_path);
		}

		$table->delete();


		// 删除控制器信息
		$db->execute( 'DELETE FROM `bone_application_frontend_controller` WHERE `application_id`='.$application_id );
		$db->execute( 'DELETE FROM `bone_application_backend_controller` WHERE `application_id`='.$application_id );


		$fso = bone::get('fso');


		$files = $db->get_result_array( 'SELECT `file` FROM  `bone_application_install_log` WHERE `application_id`='.$application_id );
		foreach($files as $file)
		{
			$file = str_replace('@frontend/', BONE_ROOT.DS, $file );
			$file = str_replace('@backend/', BONE_ROOT.DS.APP_DIR.DS, $file );
			$file = str_replace('/', DS, $file );
			if(is_dir($file))
			{
				$fso->rm_dir($file);
			}
			else
			{
				unlink($file);
			}
		}

		$db->execute( 'DELETE FROM `bone_application_install_log` WHERE `application_id`='.$application_id );

		return true;
	}


	function split_sql( $queries )
	{
		$start = 0;
		$open = false;
		$open_char = '';
		$end = strlen($queries);
		$query_split = array();
		for($i=0;$i<$end;$i++) {
			$current = substr($queries,$i,1);
			if(($current == '"' || $current == '\'')) {
				$n = 2;
				while(substr($queries,$i - $n + 1, 1) == '\\' && $n < $i) {
					$n ++;
				}
				if($n%2==0) {
					if ($open) {
						if($current == $open_char) {
							$open = false;
							$open_char = '';
						}
					} else {
						$open = true;
						$open_char = $current;
					}
				}
			}
			if(($current == ';' && !$open)|| $i == $end - 1) {
				$query_split[] = substr($queries, $start, ($i - $start + 1));
				$start = $i + 1;
			}
		}

		return $query_split;
	}


}
?>